package com.mhd.get_coupon.controller;

import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWT;
import com.mhd.entity.TUserCoupon;
import com.mhd.utils.Constants;
import com.mhd.utils.ResultVo;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/get-coupon")
public class GetCouponController {

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RabbitTemplate rabbitTemplate;


    /**
     * token颁发接口。调用投票接口之前需要访问该接口获取token。
     * - 用户提交提交手机号码，每个手机号码在每分钟内可以获取一个token。
     * - 如果在1分钟内同一个手机号码多次调用该接口，返回相同的token。
     * - 如果超出一分钟，则颁发新的token。
     */
    @GetMapping("/gettoken")
    public ResultVo getToken(String phone) throws Exception {

        // 1. 检查redis中是否有该手机号对应的token，有直接返回
        String key = Constants.REDIS_JWT_PRE+phone;
        final String redisJwt = (String) redisTemplate.opsForValue().get(key);

        if (redisJwt!=null){
            // 缓存命中了，直接返回
            return ResultVo.ok(redisJwt);
        }

        // 2. 缓存未命中
        final String newToken = JWT.create().setSubject(phone)
                .setExpiresAt(new Date(System.currentTimeMillis() + 1000 * 60))
                .setKey(Constants.SECRET.getBytes("utf-8"))
                .sign();

        // 3. 放到redis中
        redisTemplate.opsForValue().set(key,newToken);

        return ResultVo.ok(newToken);
    }

    @GetMapping("/get-coupon")
    public ResultVo dovote(@ApiParam("用户id") String id,@ApiParam("优惠券id") String couponId, String phone, @RequestHeader("token") String token) throws Exception {

        //判断用户是否已经有了优惠券  有了就不给了

        List<String> range = redisTemplate.opsForList().range(Constants.USER_HAVE_COUPONS + id, 0, -1);
        for (String s : range) {
            if (s.equals(couponId)){
                throw new Exception("用户已经有了该优惠券");
            }
        }
        //1. 判断该用户是否能够投票
        //1.1 校验 jwt 是否有效
        String subject =(String) JWT.of(token).getPayload("sub");
        if (!phone.equals(subject)){
            throw new Exception("jwt token 不合法");
        }
        final boolean validate = JWT.of(token).setKey(Constants.SECRET.getBytes("utf-8"))
                .verify();

        if (!validate){
            throw new Exception("jwt token 无效");
        }
        //token成功
        //给用户添加这张优惠券
        Object o =  redisTemplate.opsForList().rightPop(Constants.COUPON_USER_LIST+couponId);

        System.out.println(o);

         TUserCoupon oo = (TUserCoupon) o;
//
        oo.setUserId(Integer.parseInt(id));

        //暂时不存放redis  等到有用户接口后再按照用户id存放优惠券信息


        String s = JSONUtil.toJsonStr(o);
        //进行mq 生产者发送消息
        //像db发送消息  向ES发送消息
        rabbitTemplate.convertAndSend("coupon_info","www.coupon.sdsd",s);

        //给用户添加已经获得的优惠券类型
        redisTemplate.opsForList().rightPush(Constants.USER_HAVE_COUPONS+id,couponId);

        return ResultVo.ok();
    }

}

